<?php
/**
 * SCRM公用service
 * User: Guofeng
 * Date: 2022/03/10
 * Time: 上午 10:00
 */

namespace App\Services;


use Illuminate\Support\Facades\DB;

class CommonService
{

    protected static $_instances = [];

    /**
     * 过滤数据
     *
     */
    public static function filterInfo($data, $field)
    {
        if (empty($data) || empty($field)) {
            return $data;
        }

        foreach ($data as $key => $value) {
            if (is_array($value)) {
                foreach ($value as $keysub => $valuesub) {
                    if (!in_array($keysub, $field)) {
                        unset($data[$key][$keysub]);
                    }
                }
            } else {
                if (!in_array($key, $field)) {
                    unset($data[$key]);
                }
            }

        }

        return $data;

    }

    public static function beginTransaction()
    {
        DB::beginTransaction();
    }

    public static function rollBack()
    {
        DB::rollBack();
    }

    public static function commit()
    {
        DB::commit();
    }

    /**
     * 单例
     * @param $construct_parameter
     * @return static
     */
    public static function getInstance(...$construct_parameter): CommonService
    {
        if (!isset(static::$_instances[static::class])) {
            if (count($construct_parameter) > 0) {
                static::$_instances[static::class] = new static(...$construct_parameter);
            } else {
                static::$_instances[static::class] = new static();
            }

        }
        return static::$_instances[static::class];
    }

    /**
     * 效验字符串
     * 效验请求过来的参数 是否存在或是否为空
     * @param string $key
     * @param array $array
     * @return bool
     */
    protected function isExistsStr(string $key, array $array = []): bool
    {
        if (!array_key_exists($key, $array)) {
            return false;
        }


        $str = trim($array[$key]);


        return !empty($str);
    }

    /**
     * 效验数据
     * 效验请求过来的数据 是否存在或是否为空
     * @param string $key
     * @param array $array
     * @return bool
     */
    protected function isExistsArray(string $key, array $array = []): bool
    {
        if (!array_key_exists($key, $array)) {
            return false;
        }
        return !empty($array[$key]);
    }

    /**
     * SCRM 获取本月的开始结束时间
     */
    public function getMonthDate(): array
    {
        $nowTime = time();
        $monthDays = date('t', $nowTime);
        $monthStart = date('Y-m-1 00:00:00', $nowTime);
        $monthEnd = date('Y-m-' . $monthDays . ' 23:59:59', $nowTime);
        return [
            'startDate' => $monthStart,
            'endDate' => $monthEnd,
        ];
    }

    /**
     * SCRM 获取今天的开始结束时间
     */
    public function getTodayDate(): array
    {
        $nowTime = time();
        $todayStart = date('Y-m-d 00:00:00', $nowTime);
        $todayEnd = date('Y-m-d 23:59:59', $nowTime);
        return [
            'startDate' => $todayStart,
            'endDate' => $todayEnd,
        ];
    }

    /**
     * 北极星App 获取昨天的开始结束时间
     */
    public function getYesterdayDate(): array
    {
        $beginToday = date("Y-m-d", strtotime("-1 day")) . " 00:00:00";
        $endToday = date("Y-m-d", strtotime("-1 day")) . " 23:59:59";
        return [
            'startDate' => $beginToday,
            'endDate' => $endToday,
        ];
    }

    /**
     * SCRM 获取本周的开始结束时间
     */
    public function getWeekDate(): array
    {
        $date = date('Y-m-d');  //当前日期

        $first = 1; //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期

        $w = date('w', strtotime($date));  //获取当前周的第几天 周日是 0 周一到周六是 1 - 6

        $beginToday = date('Y-m-d', strtotime("$date -" . ($w ? $w - $first : 6) . ' days')) . " 00:00:00"; //获取本周开始日期，如果$w是0，则表示周日，减去 6 天

        $endToday = date('Y-m-d', strtotime("$beginToday +6 days")) . " 23:59:59";  //本周结束日期
        return [
            'startDate' => $beginToday,
            'endDate' => $endToday,
        ];
    }

    /**
     * 北极星App 获取本季度的开始结束时间
     */
    public function getQuarterDate(): array
    {
        $season = ceil((date('n')) / 3);
        $beginToday = date('Y-m-d H:i:s', mktime(0, 0, 0, $season * 3 - 3 + 1, 1, date('Y')));
        $endToday = date('Y-m-d H:i:s', mktime(23, 59, 59, $season * 3, date('t', mktime(0, 0, 0, $season * 3, 1, date("Y"))), date('Y')));
        return [
            'startDate' => $beginToday,
            'endDate' => $endToday,
        ];
    }

    /**
     * SCRM 获取本年的开始结束时间
     */
    public function getYearDate(): array
    {
        $year = date("Y", time());
        $smonth = 1;
        $emonth = 12;

        $beginToday = $year . '-' . $smonth . '-1 00:00:00';
        $em = $year . '-' . $emonth . '-1 23:59:59';
        $endToday = date('Y-m-t H:i:s', strtotime($em));

        return [
            'startDate' => $beginToday,
            'endDate' => $endToday,
        ];
    }


    /**
     * SCRM首页获取对应时间段
     * @params = [
     *   'dateType' => 1,
     *    .....
     * ];
     * @params1 用户id
     * return $array = [
     *  'startDate' => '2021-08-09 00:00',
     *  'salesArrIds' => ['销售id集合'],
     * ];
     */
    public function getDate($arrParams)
    {
        if (!is_array($arrParams)) return $this->throwException('params必须为array', 30001);
        if (!array_key_exists('dateType', $arrParams)) return $this->throwException('dateType不能为空', 30002);
        $dateType = $arrParams['dateType'];
        $timeDate = [];
        if (!in_array($dateType, [1, 2, 3, 4, 5, 6, 7])) return $this->throwException('请检查日期类型', 30003);
        switch ($dateType) {
            case 1:
                //本日
                $timeDate = $this->getTodayDate();
                break;
            case 2:
                //昨日
                $timeDate = $this->getYesterdayDate();
                break;
            case 3:
                //本周
                $timeDate = $this->getWeekDate();
                break;
            case 4:
                //本月
                $timeDate = $this->getMonthDate();
                break;
            case 5:
                //本季度
                $timeDate = $this->getQuarterDate();
                break;
            case 6:
                //本年
                $timeDate = $this->getYearDate();
                break;
            case 7:
                //自定义时间段 判断时间不可超过一年
                //校验参数不能为空
                if (!array_key_exists('startDate', $arrParams) || empty($arrParams['startDate'])) return $this->throwException('开始时间不能为空', 30004);
                if (!array_key_exists('endDate', $arrParams) || empty($arrParams['endDate'])) return $this->throwException('结束时间不能为空', 30005);
                if (strtotime($arrParams['startDate'] . " 00:00:00") >= strtotime($arrParams['endDate'] . " 23:59:59")) return $this->throwException('开始时间不能大于结束时间', 30006);
                //数据间隔不能太长
                $startData = explode("-", $arrParams['startDate']);
                $endData = explode("-", $arrParams['endDate']);
                $EndDayNum = mktime(0, 0, 0, $endData[1], $endData[2], $endData[0]);
                $startDayNum = mktime(0, 0, 0, $startData[1], $startData[2], $startData[0]);
                $days = round(($EndDayNum - $startDayNum) / 3600 / 24);
                if ($days > 365) return $this->throwException('自定义时间只能查询一年', 30006);
                $timeDate = [
                    'startDate' => $arrParams['startDate'] . " 00:00:00",
                    'endDate' => $arrParams['endDate'] . " 23:59:59",
                ];
                break;
        }
        return $timeDate;
    }


    /**
     * SCRM 抛出异常 AppExceptions
     * @param string $strMsg
     * @param int $intCode
     * @param array $data
     * @return false|string
     */
    public function throwException(string $strMsg = '', int $intCode = 10000, array $data = [])
    {
        $returnData = [
            'code' => $intCode,
            'message' => $strMsg,
            'data' => empty($data) ? [] : $data,
        ];
        return json_encode($returnData);
    }


    /**
     *   将数组转换为xml
     * @param array $data 要转换的数组
     * @param bool $root 是否要根节点
     * @return string         xml字符串
     */
    public function arrToXml(array $data, bool $root = true): string
    {
        $str = "";
        if ($root) {
            $str .= "<xml>";
        }
        foreach ($data as $key => $val) {
            if (is_array($val)) {
                $child = $this->arrToXml($val, false);
                $str .= "<$key>$child</$key>";
            } else {
                $str .= "<$key><![CDATA[$val]]></$key>";
            }
        }
        if ($root) {
            $str .= "</xml>";
        }
        return $str;
    }


    /**
     * 用户权限关系数组处理
     * @param $data
     * @param $uid
     * @param $key1
     * @param $key2
     * @return array
     */
    public function manageRoles($data, $uid, $key1, $key2): array
    {
        $updateRoles = array();
        if (isset($data[$key1]) && !empty($data[$key1])) {
            foreach ($data[$key1] as $value) {
                unset($temp);
                if ($uid) {
                    $temp[$key2] = $uid;
                }
                $temp[$key1] = $value;
                $updateRoles[] = $temp;
            }
        }

        return $updateRoles;
    }


}
